# autodist.R
# easy manipulation of mixed distributions

# distribution representation:
# (type, weight, ...)
# normal: (0, weight, mean, std_dev)
# lognormal: (1, weight, mean, std_dev)
# gamma: (2, weight, mean, std_dev)

createnorm <- function(type, w., m., sd.)
	c(type, round(w.,2), m., sd.)

changeweight <- function(distrs, d, w.) {
	distrs[[d]][2] <- distrs[[d]][2] + w.
	wsum <- 0
	for(i in 1:length(distrs))
		wsum <- wsum + distrs[[i]][2]
	for(i in 1:length(distrs))
		distrs[[i]][2] <- round(distrs[[i]][2] / wsum, 2)
	distrs
}

movenorm <- function(distrs, d, m.) {
	distrs[[d]][3] <- max(0, distrs[[d]][3] + m.)
	distrs
}

shapenorm <- function(distrs, d, sd.) {
	distrs[[d]][4] <- max(1, distrs[[d]][4] + sd.)
	distrs
}

# combines all internal distributions into a mixed one

gendist <- function(x, dist)
{
	if(dist[1] == 0)  # normal
		d <- dnorm(x, dist[3], dist[4]) * dist[2]
	else if(dist[1] == 1)  # log-normal
		d <- dlnorm(x, dist[3], dist[4])
	else if(dist[1] == 2) {  # gamma
		E <- dist[3]
		V <- dist[4]
		alpha <- (E^2)/V
		beta <- E/V
		d <- dgamma(x, alpha, beta)
	}
	else
		print(paste('Error: unknown graph:', dist[1]))
	d
}

gendists <- function(distrs, x)
{
	dist <- rep(0, length(x))
	for(d in distrs)
		dist <- dist + gendist(x, d)
	dist
}

# comparisons

is_distr <- function(d1, d2)
{
	if(length(d1) == length(d2)) {
		for(i in 1:length(d1))
			for(j in 1:length(d1[[i]]))
				if(d1[[i]][j] != d2[[i]][j])
					return(FALSE)
		return(TRUE)
	}
	FALSE
}

# error calculation: how well does it fit the data

calcerror <- function(dados, dist)
	sum(((dados - dist)^2)*c(1/7, 2/7, 3/7, 4/7, 5/7, 6/7, 1))

# fire shot; just to start from somewhere

startfit <- function(distrs_type, x, y)
{
	ndistr <- length(distrs_type)
	distrs <- vector('list', ndistr)
	q <- (x[length(x)]-x[1]) / ndistr

	q1 <- x[1]
	for(d in 1:ndistr) {
		q2 <- q1 + q

		m. <- q1 + q/2
		sd. <- q*4
#		sd. <- sd(y[(d*q.):((d+1)*q.)])
		distrs[[d]] <- createnorm(distrs_type[d], 1/ndistr, m., sd.)
		q1 <- q2
	}
	distrs
}

# prints

print_distrs <- function(distrs)
{
	for(d in distrs) {
		if(d[1] == 0)
			print(paste('normal -', round(d[2], 2), ' - media:', d[3], '- var:', d[4]))
		if(d[1] == 1)
			print(paste('lognormal -', round(d[2], 2), ' - media:', d[3], '- var:', d[4]))
		if(d[1] == 2) {
			E <- d[3]
			V <- d[4]
			alpha <- (E^2)/V
			beta <- E/V
			print(paste('gamma -', round(d[2], 2), ' - alpha:', alpha, '- beta:', beta))
		}
	}
}

